﻿/*------------------------------------------------------------------------------------------
Component    : Dicom Communication
Source file   : DicomServerHandler.cs
Author    : Hai Nguyen  
Creation Date  : 06/02/2012
Description   : This class is contain event of dicom sever.
Use Case    :this class used in Dicom Communication use case
Includes    : Statistics, Network, Dicom
Notes  : <Optional/additional comments regarding the source file> -       
Optional 
Copyright Prowess, Inc. 2011 
 
The copyright to the computer program(s) herein is the property 
of Prowess, Inc. The program(s) may be used and/or copied only 
with the written permission of Prowess, Inc. or in accordance 
with the terms and conditions stipulated in the agreement/contract 
under which the program(s) have been supplied.
 --------------------------------------------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ClearCanvas.Dicom.Network;
using ClearCanvas.Dicom.Utilities.Statistics;
using ClearCanvas.Dicom;
using System.Windows;
using System.IO;
using LynxDicomServer;
namespace Prowess.Lynx.DicomCommunicator
{
    public class DicomServerHandler : IDicomServerHandler
    {        
        #region Private Member
        private AssociationStatisticsRecorder statsRecorder;
        private String folderName = String.Empty;
        private Form1 mainForm;
        #endregion

        #region Constructor
        public DicomServerHandler(DicomServer server, ServerAssociationParameters association,String folderNameInput,Form1 mainFormInput)
        {
            statsRecorder = new AssociationStatisticsRecorder(server);
            folderName = folderNameInput;
            mainForm = mainFormInput;
        }
        #endregion

        #region IDicomServerHandler Members

        public void OnReceiveAssociateRequest(DicomServer server, ServerAssociationParameters association)
        {
            //throw new NotImplementedException();
            server.SendAssociateAccept(association);
        }
        List<string> patient = new List<string>();
        DirectoryInfo direc_toryinfo = new DirectoryInfo("D:\\test");
        public void OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, ClearCanvas.Dicom.DicomMessage message)
        {
            FileInfo[] files = direc_toryinfo.GetFiles();
            if (message.DataSet.Count == 0)
            {
                //Verifier
                server.SendCEchoResponse(presentationID, message.MessageId, DicomStatuses.Success);
                mainForm.SetLog("Verified Success");
            }
            else
            {
                if (message.CommandField==DicomCommandField.CFindRequest)
                {
                   
                    
                    string patientid_find = get_information(message.DataSet[DicomTags.PatientId]);

                    string study_instanceuid_find = get_information(message.DataSet[DicomTags.StudyInstanceUid]);
                    int i = 0;
                   if (patientid_find==""&&study_instanceuid_find=="")
                   {
                       foreach (FileInfo file in files)
                       {
                           i++;
                           DicomFile dicomfile = new DicomFile(file.FullName);
                           dicomfile.Load();
                          
                          if (patient.Contains(get_information(dicomfile.DataSet[DicomTags.StudyInstanceUid]))==false)
                          {
                              patient.Add(get_information(dicomfile.DataSet[DicomTags.StudyInstanceUid]));
                              message.DataSet[DicomTags.PatientId].SetStringValue(get_information(dicomfile.DataSet[DicomTags.PatientId]));
                              message.DataSet[DicomTags.PatientsName].SetStringValue(get_information(dicomfile.DataSet[DicomTags.PatientsName]));
                              message.DataSet[DicomTags.PatientsSex].SetStringValue(get_information(dicomfile.DataSet[DicomTags.PatientsSex]));
                              message.DataSet[DicomTags.PatientsBirthDate].SetDateTime(0, dicomfile.DataSet[DicomTags.PatientsBirthDate].GetDateTime(0));
                              message.DataSet[DicomTags.StudyInstanceUid].SetStringValue(get_information(dicomfile.DataSet[DicomTags.StudyInstanceUid]));
                              message.DataSet[DicomTags.StudyId].SetStringValue(get_information(dicomfile.DataSet[DicomTags.StudyId]));
                              message.DataSet[DicomTags.SeriesDate].SetStringValue(get_information(dicomfile.DataSet[DicomTags.SeriesDate]));
                              server.SendCFindResponse(presentationID, message.MessageId, message, DicomStatuses.Pending);
                              server.SendCFindResponse(presentationID, message.MessageId, message, DicomStatuses.Success);
                          }
                           //dicomfile.DataSet[DicomTags.PatientsBirthDate].GetDateTime(0);
                       }
                   }
                    if (study_instanceuid_find == ""&&patientid_find!="")
                   {
                       foreach (FileInfo file in files)
                       {
                           DicomFile dicomfile = new DicomFile(file.FullName);
                           dicomfile.Load();
                           string patientid = get_information(message.DataSet[DicomTags.PatientId]);
                           if (patient.Contains(get_information(dicomfile.DataSet[DicomTags.StudyInstanceUid])) == false)
                           {
                               if (patientid_find == patientid)
                               {

                                   patient.Add(get_information(dicomfile.DataSet[DicomTags.StudyInstanceUid]));
                                   patient.Add(get_information(dicomfile.DataSet[DicomTags.StudyInstanceUid]));
                                   message.DataSet[DicomTags.PatientId].SetStringValue(get_information(dicomfile.DataSet[DicomTags.PatientId]));
                                   message.DataSet[DicomTags.PatientsName].SetStringValue(get_information(dicomfile.DataSet[DicomTags.PatientsName]));
                                   message.DataSet[DicomTags.PatientsSex].SetStringValue(get_information(dicomfile.DataSet[DicomTags.PatientsSex]));
                                   message.DataSet[DicomTags.PatientsBirthDate].SetDateTime(0, dicomfile.DataSet[DicomTags.PatientsBirthDate].GetDateTime(0));
                                   message.DataSet[DicomTags.StudyInstanceUid].SetStringValue(get_information(dicomfile.DataSet[DicomTags.StudyInstanceUid]));
                                   message.DataSet[DicomTags.StudyId].SetStringValue(get_information(dicomfile.DataSet[DicomTags.StudyId]));
                                   message.DataSet[DicomTags.SeriesDate].SetStringValue(get_information(dicomfile.DataSet[DicomTags.SeriesDate]));
                                   server.SendCFindResponse(presentationID, message.MessageId, message, DicomStatuses.Pending);
                                   server.SendCFindResponse(presentationID, message.MessageId, message, DicomStatuses.Success);

                               }

                           }
                           


                       }
                   }
                   if(study_instanceuid_find!=""&&patientid_find=="")

                   {
                       foreach (FileInfo file in files)
                       {
                           DicomFile dicomfile = new DicomFile(file.FullName);
                           dicomfile.Load();
                           
                           string studyinstanceuid = get_information(message.DataSet[DicomTags.StudyInstanceUid]);
                          // string patientid = get_information(message.DataSet[DicomTags.PatientId]);
                           if (patient.Contains(get_information(dicomfile.DataSet[DicomTags.SeriesInstanceUid])) == false)
                           {
                               if (study_instanceuid_find == studyinstanceuid)
                               {


                                   patient.Add(get_information(dicomfile.DataSet[DicomTags.SeriesInstanceUid]));
                                   message.DataSet[DicomTags.SeriesInstanceUid].SetStringValue(get_information(dicomfile.DataSet[DicomTags.SeriesInstanceUid]));
                                   server.SendCFindResponse(presentationID, message.MessageId, message, DicomStatuses.Pending);
                                   server.SendCFindResponse(presentationID, message.MessageId, message, DicomStatuses.Success);


                               }
                           }
                          


                       }
                   }
                    //DicomMessage _respone = new DicomMessage();                    
                    //////DicomMessage _mss = new DicomMessage();
                    
                    //message.DataSet[DicomTags.PatientId].SetStringValue("aaaa");
                    //message.DataSet[DicomTags.PatientsName].SetStringValue("aaaa");
                    //message.DataSet[DicomTags.PatientsSex].SetStringValue("aaaa");
                    ////message.DataSet[DicomTags.PatientsBirthDate].SetStringValue("aaaa");
                    //message.DataSet[DicomTags.StudyId].SetStringValue("aaaa");
                    //message.DataSet[DicomTags.StudyInstanceUid].SetStringValue("bbbb");
                    //// message.DataSet[DicomTags.StudyDate].SetStringValue("aaaa");
                    ////message.DataSet[DicomTags.StudyTime].SetStringValue("aaaa");
                    //message.DataSet[DicomTags.Modality].SetStringValue("aaaa");
                    ////message.DataSet[DicomTags.SeriesNumber].SetStringValue("aaaa");
                    ////message.DataSet[DicomTags.SeriesDate].SetStringValue("aaaa");
                    ////message.DataSet[DicomTags.SeriesTime].SetStringValue("aaaa");

                    //string query = message.DataSet[DicomTags.QueryRetrieveLevel].GetString(0, "");
                    

                  //  server.SendCFindResponse(presentationID, message.MessageId,message, DicomStatuses.Pending);
                    //server.SendCFindResponse(presentationID, message.MessageId,_respone,DicomStatuses.Success);

                }
                else if (message.CommandField==DicomCommandField.CStoreRequest)
                {
                    //Received dicom object
                    DicomUid sopInstanceUid;
                    
                    bool ok = message.DataSet[DicomTags.SopInstanceUid].TryGetUid(0, out sopInstanceUid);
                    if (ok)
                    {
                        //Stored Dicom object
                        
                        
                        string fileName = sopInstanceUid.ToString();
                        string path = String.Format("{0}\\{1}.dcm", folderName, fileName);
                        
                        try
                        {
                            DicomFile dicomFile = new DicomFile(message, path);
                            
                            if (message.TransferSyntax.Encapsulated)
                                dicomFile.TransferSyntax = message.TransferSyntax;
                            //else
                            //    dicomFile.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;
                            
                            dicomFile.MediaStorageSopInstanceUid = sopInstanceUid.UID;
                            dicomFile.ImplementationClassUid = DicomImplementation.ClassUID.UID;
                            dicomFile.ImplementationVersionName = DicomImplementation.Version;
                            dicomFile.SourceApplicationEntityTitle = association.CallingAE;
                            dicomFile.MediaStorageSopClassUid = message.SopClass.Uid;

                            dicomFile.Save(DicomWriteOptions.None);


                            server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID, DicomStatuses.Success);
                                                      
                            mainForm.SetLog("Received Dicom Object: " + sopInstanceUid.UID.ToString());
                        }
                        catch (Exception ex)
                        {
                            server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID,
                                DicomStatuses.ProcessingFailure);
                            mainForm.SetLog(ex.Message);
                        }
                    }
                    else
                    {
                        //Response for Client transfer next object
                        server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID,
                        DicomStatuses.ProcessingFailure);

                        mainForm.SetLog("Received processing Failure");
                    }                
                }
                if (message.CommandField==DicomCommandField.CMoveRequest)
                {
                   
                    string serries_instanceuid = get_information(message.DataSet[DicomTags.SeriesInstanceUid]);
                    string study_instanceuid = get_information(message.DataSet[DicomTags.StudyInstanceUid]);
                    StorageScu store_scu = new StorageScu();
                    
                    if (serries_instanceuid!="")
                    {
                        foreach (FileInfo file in files)
                        {
                            DicomFile dicomfile = new DicomFile(file.FullName);
                            dicomfile.Load();
                            string seriesinstanceuid_infile = get_information(dicomfile.DataSet[DicomTags.SeriesInstanceUid]);
                            if (serries_instanceuid == seriesinstanceuid_infile)
                            {
                                store_scu.AddFileToSend(file.FullName);
                                store_scu.Send("TEST_AE", message.MoveDestination, "127.0.0.1", 8125);
                                server.SendCMoveResponse(presentationID, message.MessageId, message, DicomStatuses.Pending);
                                server.SendCMoveResponse(presentationID, message.MessageId, message, DicomStatuses.Success);
                            }
                        }
                       
                    }
                    else if (study_instanceuid!="")
                    {
                        foreach (FileInfo file in files)
                        {
                            DicomFile dicomfile = new DicomFile(file.FullName);
                            dicomfile.Load(DicomTags.StudyInstanceUid, DicomReadOptions.Default);
                            string studyinstanceuid_infile = get_information(dicomfile.DataSet[DicomTags.StudyInstanceUid]);
                            if (study_instanceuid == studyinstanceuid_infile)
                            {
                                store_scu.AddFileToSend(file.FullName);
                                store_scu.Send("TEST_AE", "testae", "127.0.0.1", 8124);
                                server.SendCMoveResponse(presentationID, message.MessageId, message, DicomStatuses.Pending);
                                server.SendCMoveResponse(presentationID, message.MessageId, message, DicomStatuses.Success);
                            }
                        }
                    }
                    //server.SendCMoveResponse(presentationID, message.MessageId, message, DicomStatuses.Pending);
                   // server.SendCStoreResponse()
                }
               
                
            }
        }

        private string get_information(DicomAttribute dicomAttribute)
        {
            string chuoi = "";
            try
            {
               

                if (dicomAttribute.Values.GetType() == typeof(string))
                {
                    chuoi = (string)dicomAttribute.Values;

                }
                if (dicomAttribute.Values.GetType() == typeof(string[]))
                {

                    string[] mangnhan = (string[])dicomAttribute.Values;
                    for (int i = 0; i < mangnhan.Length; i++)
                    {
                        chuoi += mangnhan[i];
                    }

                }
 
            }
            catch (System.Exception ex)
            {
            	

            }
            return chuoi;
        }

        
        public void OnReceiveResponseMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, ClearCanvas.Dicom.DicomMessage message)
        {
            server.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.UnexpectedPDU);
        }

        public void OnReceiveReleaseRequest(DicomServer server, ServerAssociationParameters association)
        {
            server.SendReleaseRequest();
            
        }

       public void OnReceiveAbort(DicomServer server, ServerAssociationParameters association, DicomAbortSource source, DicomAbortReason reason)
        {
            server.SendAssociateAbort(DicomAbortSource.ServiceProvider, DicomAbortReason.UnexpectedPDU);
        }

       public void OnNetworkError(DicomServer server, ServerAssociationParameters association, Exception e)
        {
            
        }

        public void OnDimseTimeout(DicomServer server, ServerAssociationParameters association)
        {
           
        }

        public void OnCompletedReceived()
        {
            
        }
        #endregion

        #region IDicomServerHandler Members        

        

        #endregion
    }
}
